home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / APPLICAT / C034.ZIP / NLONG.C < prev    next >
Text File  |  2010-11-01  |  8KB  |  352 lines

  1. /*
  2.  
  3. Long package amended and extended to support BDS 1.50 library
  4.  
  5. added    lcomp - compare two strings (as per documentation)
  6.     ltoas - long to ascii scaled
  7.     atols - ascii to long scaled
  8.  
  9.     function numbers 0,7,8 have not yet been identified
  10.     and are marked as UK1,UK3,UK4 below.
  11.  
  12.     a few functions in the documentation have not been done
  13.     yet but are trivial to implement when required.
  14.  
  15. */
  16. #define   UK1     0
  17. #define   COMP    1
  18. #define   ADD     2
  19. #define   SUB     3
  20. #define   MUL     4
  21. #define   DIV     5
  22. #define   MOD     6
  23. #define   UK3     7
  24. #define   UK4     8
  25.  
  26. /*   ladd adds the addend and augend to produce a 32 bit
  27.    signed result in sum.  A pointer to sum is returned.  */
  28.  
  29. char *ladd(sum,addend,augend)
  30. char sum[], addend[], augend[];
  31. {
  32.     char *long();
  33.     return (long(ADD,sum,addend,augend));
  34. }
  35.  
  36. /*   lsub subtracts subtrahend from minuend and places the
  37.    32 bit signed difference in difference.  A pointer to
  38.    difference is returned.                              */
  39.  
  40. char *lsub(difference,minuend,subtrahend)
  41. char difference[], minuend[], subtrahend[];
  42. {
  43.     char *long();
  44.     return (long(SUB,difference,minuend,subtrahend));
  45. }
  46.  
  47. /*   lmul multiplies plier and plicand together and places
  48.    the signed low order 32 bit product in product.  A
  49.    pointer to product is returned.                      */
  50.  
  51. char *lmul(product,plier,plicand)
  52. char product[], plier[], plicand[];
  53. {
  54.     char *long();
  55.     return (long(MUL,product,plier,plicand));
  56. }
  57.  
  58. /*    scale must be from 0 to 9    */
  59.  
  60. char *lmuls(product,plier,plicand,scale)
  61. char product[],plier[],plicand[]; int scale;
  62. {
  63.     char *long();
  64.     char ten[4],five[4];
  65.     ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
  66.     five[3]=0x05; five[1]=five[2]=five[0]=0;
  67.  
  68.     long(MUL,product,plier,plicand);
  69.         /*    round and scale        */
  70.     while (scale--) {
  71.         long(ADD,product,product,five);
  72.         long(DIV,product,product,ten);
  73.     }
  74.     return(&product);
  75. }    
  76.  
  77. /*   ldiv divides dividend by divisor and places the signed
  78.    low order 32 bits of the quotient in quotient.  A
  79.    pointer to quotient is returned.
  80.    ldivs takes account of a scale when performing the
  81.    division - 0 <= scale < 10                   */
  82.  
  83. char *ldiv(quotient,dividend,divisor)
  84. char quotient[], dividend[], divisor[];
  85. {
  86.     char *long();
  87.     return (long(DIV,quotient,dividend,divisor));
  88. }
  89.  
  90.  
  91. char *ldivs(quotient,dividend,divisor,scale)
  92. char quotient[], dividend[], divisor[]; int scale;
  93. {
  94.     char *long();
  95.     char ten[4];
  96.     ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
  97.  
  98.     while (scale--)
  99.         long(MUL,dividend,dividend,ten);
  100.     long(DIV,quotient,dividend,divisor);
  101. }
  102.  
  103. /*   lmod places the 31 bit positive remainder resulting
  104.    from the division of dividend by divisor into residue.
  105.    A pointer to residue is returned.                   */
  106.  
  107. char *lmod(residue,dividend,divisor)
  108. char residue[], dividend[], divisor[];
  109. {
  110.     char *long();
  111.  
  112.     
  113.     return (long(MOD,residue,dividend,divisor));
  114. }
  115.  
  116. /*   lneg places the 32 bit signed negative of orignum in
  117.    negnum and returns a pointer to it.                  */
  118.  
  119. char *lneg(negnum,orignum)
  120. char negnum[], orignum[];
  121. {
  122.     char *long(), work[4], i;
  123.     for (i=0; i<4; ++i) work[i]=0;
  124.     return (long(SUB,negnum,work,orignum));
  125. }
  126.  
  127. /*   lcomp returns -1,0,1 depending on result of left<right,l=r,l>r  */
  128.  
  129. int lcomp(left,right)
  130. char left[], right[];
  131. {
  132.     return(long(COMP,left,right));
  133. }
  134.  
  135. /*   itol converts an integer to long form.  A pointer
  136.    to the longform is returned.                       */
  137.  
  138. char *itol(longform,i)
  139. char longform[];
  140. int i;
  141. {
  142.     longform[1]=longform[0]=0;
  143.     if (i<0) longform[1]=longform[0]=0xff;
  144.     longform[2]=i>>8;
  145.     longform[3]=i&0xff;
  146.     return longform;
  147. }
  148.  
  149. /*   ltoi returns a properly signed integer containing the
  150.    low order 15 bits of precision of the long integer
  151.     longint.  The value of this integer is placed in i and
  152.    is returned by this function.                         */
  153.  
  154. ltoi(longint)
  155. char longint[4];
  156. {
  157.     int i;
  158.     char work[4];
  159.  
  160.     for (i=0; i<4; ++i) work[i]=longint[i];
  161.     if (work[0]>127) lneg(work,work);
  162.     i=(work[2]<<8)+work[3];
  163.     if (longint[0]>127) i=-i;
  164.     return i;
  165. }
  166.  
  167. /*   atol converts the ASCII string s to a long integer
  168.    placed in longint and returns a pointer to longint.
  169.    Acceptable format for atol is:  any amount of white
  170.    space followed by an optional sign followed by a string
  171.    of decimal digits.  The first non-decimal digit stops
  172.    the scan.  The method used is an adaptation of that
  173.    presented in Kernighan and Ritchie.                */
  174.  
  175. char *atols(longint,s,scale)
  176. char longint[]; char s[]; int scale;
  177. {
  178.     int i, j;
  179.     char wstr[20];
  180.     char *wptr,*sptr;
  181.  
  182.     sptr = &s[0];
  183.     wptr = &wstr[0];
  184.  
  185.  
  186. /* white space */
  187.     while (*sptr == ' ' || *sptr == '\t')
  188.         sptr++;
  189. /* a sign */
  190.     if (*sptr == '-' || *sptr == '+')
  191.         *wptr++ = *sptr++;
  192.  
  193. /* integral digits */
  194.     while (isdigit(*sptr))
  195.         *wptr++ = *sptr++;
  196.  
  197. /* have we got a dot */
  198.     if (*sptr == '.') {
  199.         sptr++;
  200.         while (scale--)
  201.             if (isdigit(*sptr))
  202.                 *wptr++ = *sptr++;
  203.             else
  204.                 *wptr++ = '0';
  205.         }
  206.     else
  207.         while (scale--)
  208.             *wptr++ = '0';
  209. /* end of string */
  210.     *wptr++ = 0;
  211.  
  212.     return(atol(longint,wstr));
  213. }    
  214.     
  215.  
  216. char *atol(longint,s)
  217. char longint[], s[];
  218. {
  219.     char work[4], ten[4];
  220.     int i, j, n, sign;
  221.     /* form a constant.. */
  222.  
  223.     ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
  224.     /*   first skip white space... */
  225.     for (i=0; s[i]==' ' || s[i]=='\n' || s[i]=='\t'; i++);
  226.  
  227.     /*   now get the sign... */
  228.  
  229.     sign=1;
  230.     if (s[i]=='+' || s[i]=='-')
  231.         sign=(s[i++]=='+') ? 1 : -1;
  232.  
  233.     /*   and convert the string straightforwardly... */
  234.  
  235.     for (j=0; j<4; ++j) longint[j]=0;
  236.     while (s[i]>='0' && s[i]<='9') {
  237.         for (j=0; j<4; ++j) work[j]=0;
  238.         work[3]=s[i++]-'0';
  239.         lmul(longint,ten,longint);
  240.         ladd(longint,longint,work);
  241.     }
  242.  
  243.     /*   not forgetting the original sign... */
  244.  
  245.     if (sign==-1) lneg(longint,longint);
  246.     return longint;
  247. }
  248.  
  249. /*   ltoa converts the long integer longint to an ASCII
  250.    string which is placed in s.  If longint is negative a
  251.    minus sign is prefixes the string.  The algorithm used
  252.    is an adaptation of itoa presented in Kernighan and
  253.    Ritchie.                                          */
  254.  
  255. ltoas(sptr,inlong,scale)
  256. char *sptr; char inlong[]; int scale;
  257. {
  258.     int i, j;
  259.     char work[20];
  260.     char *wptr,*fptr,*tptr;
  261.  
  262. /* Special case - get rid of integers */
  263.  
  264.     if (scale == 0)
  265.         return(ltoa(sptr,inlong));
  266.  
  267. /*    get the full string    */
  268.  
  269.     ltoa(work,inlong);
  270.  
  271.     wptr = &work[0];
  272.  
  273. /*    minimum length        */
  274.  
  275.     if (*wptr == '-')
  276.         j = scale + 3;
  277.     else
  278.         j = scale + 2;
  279.  
  280.     i = strlen(wptr) + 1;
  281.  
  282.     if (j < i)
  283.         j = i;
  284.  
  285. /*    point at last digits    */
  286.  
  287.     fptr = &wptr[i-2];
  288.     tptr = sptr + j;
  289.     *tptr-- = 0;
  290.  
  291.     while (scale--)
  292.         if ((fptr < wptr) || (*fptr == '-'))
  293.             *tptr-- = '0';
  294.         else
  295.             *tptr-- = *fptr--;
  296.  
  297.     *tptr-- = '.';
  298.     if ((fptr < wptr) || (*fptr == '-'))
  299.         *tptr-- = '0';
  300.  
  301.     while (fptr >= wptr)
  302.         *tptr-- = *fptr--;
  303.  
  304.     return (sptr);
  305. }
  306.  
  307. ltoa(s,inlong)
  308. char s[], inlong[];
  309. {
  310.     char c, work[4], ten[4], longint[4];
  311.     int i, j, k, sign;
  312.  
  313.     ten[3]=0x0a; ten[1]=ten[2]=ten[0]=0;
  314.     sign=1;
  315.  
  316.     for(i=0 ; i<4 ; i++) longint[i] = inlong[i];
  317.  
  318.     /*   check the sign... */
  319.  
  320.     if (longint[0]>127) {
  321.         sign=-1;
  322.  
  323.         lneg(longint,longint);
  324.     }
  325.  
  326.     /*   convert, generating digits backwards in s[]... */
  327.  
  328.     i=0;
  329.     do {
  330.         lmod(work,longint,ten);
  331.         s[i++]=work[3]+'0';
  332.         ldiv(longint,longint,ten);
  333.  
  334.     } while ((longint[0]|longint[1]|longint[2]|
  335.         longint[3])!=0);
  336.  
  337.     /*   postfix a minus sign if needed... */
  338.  
  339.     if (sign==-1) s[i++]='-';
  340.     s[i]='\0';
  341.  
  342.     /*   and turn the whole thing around in place. */
  343.  
  344.     k=strlen(s);
  345.     for (i=0, j=k-1; i<j; i++, j--) {
  346.         c=s[i]; s[i]=s[j]; s[j]=c;
  347.     }
  348.     return s;
  349. }
  350. ing around in place. */
  351.  
  352.     k=strlen(s);